﻿using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using Sunny.UI;

namespace MultiDAQ_Analysis.Util
{
    /// <summary>
    /// 通用打印功能工具类
    /// 提供文本内容的打印功能，支持自动分页和格式化
    /// </summary>
    public class PrintUtility : IDisposable
    {
        #region 私有字段
        private PrintDocument printDocument;
        private string[] printLines;
        private int printLineIndex;
        private string documentTitle;
        private Font titleFont;
        private Font contentFont;
        private bool isDisposed = false;
        #endregion

        #region 构造函数和析构
        /// <summary>
        /// 初始化打印工具
        /// </summary>
        /// <param name="title">文档标题</param>
        /// <param name="titleFontSize">标题字体大小</param>
        /// <param name="contentFontSize">内容字体大小</param>
        public PrintUtility(string title = "打印文档", float titleFontSize = 12F, float contentFontSize = 9F)
        {
            documentTitle = title;
            titleFont = new Font("宋体", titleFontSize, FontStyle.Bold);
            contentFont = new Font("宋体", contentFontSize);

            InitializePrintDocument();
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (!isDisposed)
            {
                printDocument?.Dispose();
                titleFont?.Dispose();
                contentFont?.Dispose();
                isDisposed = true;
            }
        }

        ~PrintUtility()
        {
            Dispose();
        }
        #endregion

        #region 初始化方法
        /// <summary>
        /// 初始化打印文档
        /// </summary>
        private void InitializePrintDocument()
        {
            printDocument = new PrintDocument();
            printDocument.PrintPage += PrintDocument_PrintPage;
            printDocument.DocumentName = documentTitle;
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 执行打印操作
        /// </summary>
        /// <param name="content">要打印的文本内容</param>
        /// <param name="showPrintDialog">是否显示打印对话框</param>
        /// <param name="parentForm">父窗体</param>
        /// <returns>打印是否成功</returns>
        public bool Print(string content, bool showPrintDialog = true, Form parentForm = null)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(content))
                {
                    UIMessageBox.ShowWarning("没有可打印的内容！");
                    return false;
                }

                // 准备打印数据
                printLines = content.Split('\n');
                printLineIndex = 0;

                if (showPrintDialog)
                {
                    // 显示打印对话框
                    using (var printDialog = new PrintDialog())
                    {
                        printDialog.Document = printDocument;
                        printDialog.UseEXDialog = true;

                        if (printDialog.ShowDialog(parentForm) == DialogResult.OK)
                        {
                            printDocument.Print();
                            UIMessageBox.ShowSuccess("打印任务已发送到打印机！");
                            return true;
                        }
                        return false;
                    }
                }
                else
                {
                    // 直接打印到默认打印机
                    printDocument.Print();
                    UIMessageBox.ShowSuccess("打印任务已发送到默认打印机！");
                    return true;
                }
            }
            catch (Exception ex)
            {
                UIMessageBox.ShowError($"打印失败：{ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 显示打印预览
        /// </summary>
        /// <param name="content">要预览的文本内容</param>
        /// <param name="parentForm">父窗体</param>
        public void ShowPrintPreview(string content, Form parentForm = null)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(content))
                {
                    UIMessageBox.ShowWarning("没有可预览的内容！");
                    return;
                }

                // 准备打印数据
                printLines = content.Split('\n');
                printLineIndex = 0;

                using (var printPreviewDialog = new PrintPreviewDialog())
                {
                    printPreviewDialog.Document = printDocument;
                    printPreviewDialog.WindowState = FormWindowState.Maximized;
                    printPreviewDialog.ShowDialog(parentForm);
                }
            }
            catch (Exception ex)
            {
                UIMessageBox.ShowError($"打印预览失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 设置文档标题
        /// </summary>
        /// <param name="title">新标题</param>
        public void SetDocumentTitle(string title)
        {
            documentTitle = title ?? "打印文档";
            if (printDocument != null)
            {
                printDocument.DocumentName = documentTitle;
            }
        }
        #endregion

        #region 打印事件处理
        /// <summary>
        /// 打印文档的PrintPage事件处理
        /// </summary>
        private void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
        {
            try
            {
                // 设置边距
                float leftMargin = e.MarginBounds.Left;
                float topMargin = e.MarginBounds.Top;
                float yPos = topMargin;
                float lineHeight = contentFont.GetHeight(e.Graphics);

                // 打印标题
                int currentPage = (printLineIndex == 0) ? 1 : (printLineIndex / GetLinesPerPage(e) + 1);
                string title = $"{documentTitle} - 第{currentPage}页";
                e.Graphics.DrawString(title, titleFont, Brushes.Black, leftMargin, yPos);
                yPos += titleFont.GetHeight(e.Graphics) * 2;

                // 计算每页可打印的行数
                int linesPerPage = GetLinesPerPage(e);
                int linesOnThisPage = 0;

                // 打印文本内容
                while (printLineIndex < printLines.Length && linesOnThisPage < linesPerPage)
                {
                    string line = printLines[printLineIndex];

                    // 检查是否需要换行（行太长）
                    SizeF textSize = e.Graphics.MeasureString(line, contentFont);
                    if (textSize.Width > e.MarginBounds.Width && line.Length > 10)
                    {
                        // 分割长行
                        int charsPerLine = CalculateCharsPerLine(line, e.MarginBounds.Width, e.Graphics);
                        if (charsPerLine > 0)
                        {
                            string subLine = line.Substring(0, Math.Min(charsPerLine, line.Length));
                            e.Graphics.DrawString(subLine, contentFont, Brushes.Black, leftMargin, yPos);

                            if (line.Length > charsPerLine)
                            {
                                printLines[printLineIndex] = line.Substring(charsPerLine);
                            }
                            else
                            {
                                printLineIndex++;
                            }
                        }
                        else
                        {
                            e.Graphics.DrawString(line, contentFont, Brushes.Black, leftMargin, yPos);
                            printLineIndex++;
                        }
                    }
                    else
                    {
                        e.Graphics.DrawString(line, contentFont, Brushes.Black, leftMargin, yPos);
                        printLineIndex++;
                    }

                    yPos += lineHeight;
                    linesOnThisPage++;
                }

                // 判断是否还有更多页需要打印
                e.HasMorePages = (printLineIndex < printLines.Length);
            }
            catch (Exception ex)
            {
                UIMessageBox.ShowError($"打印过程中发生错误：{ex.Message}");
                e.HasMorePages = false;
            }
        }

        /// <summary>
        /// 计算每页可打印的行数
        /// </summary>
        private int GetLinesPerPage(PrintPageEventArgs e)
        {
            float lineHeight = contentFont.GetHeight(e.Graphics);
            float titleHeight = titleFont.GetHeight(e.Graphics) * 2;
            return (int)((e.MarginBounds.Height - titleHeight) / lineHeight);
        }

        /// <summary>
        /// 计算每行可容纳的字符数
        /// </summary>
        private int CalculateCharsPerLine(string line, float maxWidth, Graphics graphics)
        {
            if (string.IsNullOrEmpty(line)) return 0;

            SizeF textSize = graphics.MeasureString(line, contentFont);
            if (textSize.Width <= maxWidth) return line.Length;

            // 二分查找最适合的字符数
            int left = 1;
            int right = line.Length;
            int result = 1;

            while (left <= right)
            {
                int mid = (left + right) / 2;
                string subLine = line.Substring(0, mid);
                SizeF subSize = graphics.MeasureString(subLine, contentFont);

                if (subSize.Width <= maxWidth)
                {
                    result = mid;
                    left = mid + 1;
                }
                else
                {
                    right = mid - 1;
                }
            }

            return Math.Max(1, result - 5); // 留一些边距
        }
        #endregion

        #region 静态便捷方法
        /// <summary>
        /// 快速打印文本内容的静态方法
        /// </summary>
        /// <param name="content">要打印的内容</param>
        /// <param name="title">文档标题</param>
        /// <param name="parentForm">父窗体</param>
        /// <returns>打印是否成功</returns>
        public static bool QuickPrint(string content, string title = "打印文档", Form parentForm = null)
        {
            using (var printUtility = new PrintUtility(title))
            {
                return printUtility.Print(content, true, parentForm);
            }
        }

        /// <summary>
        /// 快速显示打印预览的静态方法
        /// </summary>
        /// <param name="content">要预览的内容</param>
        /// <param name="title">文档标题</param>
        /// <param name="parentForm">父窗体</param>
        public static void QuickPreview(string content, string title = "打印文档", Form parentForm = null)
        {
            using (var printUtility = new PrintUtility(title))
            {
                printUtility.ShowPrintPreview(content, parentForm);
            }
        }
        #endregion
    }

    /// <summary>
    /// 打印按钮辅助类
    /// 用于快速为窗体添加打印按钮
    /// </summary>
    public static class PrintButtonHelper
    {
        /// <summary>
        /// 创建标准打印按钮
        /// </summary>
        /// <param name="content">要打印的内容提供者</param>
        /// <param name="title">文档标题</param>
        /// <param name="parentForm">父窗体</param>
        /// <returns>配置好的打印按钮</returns>
        public static UIButton CreatePrintButton(Func<string> content, string title = "打印文档", Form parentForm = null)
        {
            var btnPrint = new UIButton
            {
                Text = "打印",
                Size = new Size(100, 40),
                FillColor = Color.FromArgb(24, 144, 255),
                ForeColor = Color.White,
                Cursor = Cursors.Hand
                //Anchor = AnchorStyles.Bottom | AnchorStyles.Right
            };

            btnPrint.Click += (sender, e) =>
            {
                try
                {
                    string printContent = content?.Invoke();
                    if (!string.IsNullOrWhiteSpace(printContent))
                    {
                        PrintUtility.QuickPrint(printContent, title, parentForm);
                    }
                    else
                    {
                        UIMessageBox.ShowWarning("没有可打印的内容！");
                    }
                }
                catch (Exception ex)
                {
                    UIMessageBox.ShowError($"打印失败：{ex.Message}");
                }
            };

            return btnPrint;
        }

        /// <summary>
        /// 创建带预览功能的打印按钮组
        /// </summary>
        /// <param name="content">要打印的内容提供者</param>
        /// <param name="title">文档标题</param>
        /// <param name="parentForm">父窗体</param>
        /// <returns>包含打印和预览按钮的面板</returns>
        public static Panel CreatePrintButtonGroup(Func<string> content, string title = "打印文档", Form parentForm = null)
        {
            // 使用FlowLayoutPanel替代普通Panel
            var panel = new FlowLayoutPanel
            {
                AutoSize = true,
                AutoSizeMode = AutoSizeMode.GrowAndShrink,
                FlowDirection = FlowDirection.LeftToRight,
                WrapContents = false,
                Padding = new Padding(4),
                Margin = new Padding(8)
            };

            var btnPrint = new UIButton
            {
                Text = "打印",
                Size = new Size(100, 40),
                FillColor = Color.FromArgb(24, 144, 255),
                ForeColor = Color.White,
                Cursor = Cursors.Hand,
                Margin = new Padding(0, 0, 8, 0) // 右边距8像素
            };

            var btnPreview = new UIButton
            {
                Text = "打印预览",
                Size = new Size(100, 40),
                FillColor = Color.FromArgb(103, 194, 58),
                ForeColor = Color.White,
                Cursor = Cursors.Hand,
                Margin = new Padding(0)
            };

            // 事件处理保持不变
            btnPrint.Click += (sender, e) =>
            {
                try
                {
                    string printContent = content?.Invoke();
                    if (!string.IsNullOrWhiteSpace(printContent))
                    {
                        PrintUtility.QuickPrint(printContent, title, parentForm);
                    }
                    else
                    {
                        UIMessageBox.ShowWarning("没有可打印的内容！");
                    }
                }
                catch (Exception ex)
                {
                    UIMessageBox.ShowError($"打印失败：{ex.Message}");
                }
            };

            btnPreview.Click += (sender, e) =>
            {
                try
                {
                    string printContent = content?.Invoke();
                    if (!string.IsNullOrWhiteSpace(printContent))
                    {
                        PrintUtility.QuickPreview(printContent, title, parentForm);
                    }
                    else
                    {
                        UIMessageBox.ShowWarning("没有可预览的内容！");
                    }
                }
                catch (Exception ex)
                {
                    UIMessageBox.ShowError($"预览失败：{ex.Message}");
                }
            };

            panel.Controls.Add(btnPrint);
            panel.Controls.Add(btnPreview);

            return panel;
        }
    }
}